package com.jenkin.jcache.realize;

import java.util.Calendar;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import com.jenkin.jcache.Exception.ExpirationSecondsException;
import com.jenkin.jcache.base.CacheData;

/**
 * 缓存工厂，从这里得到缓存对象
 * @author yangjie
 *
 */
public class CacheFactory {
	
	//最小过期秒数
	private final static int minExpirationSeconds = 5;
	
	/**
	 * 得到哈希表类型的缓存
	 * @param masterKey
	 * @param expirationSeconds
	 * @return
	 */
	public static<K,V> MapCache<K,V> getMapCache(String masterKey, int expirationSeconds) {
		
		if (expirationSeconds < minExpirationSeconds) {
			throw new ExpirationSecondsException("缓存过期秒数不能小于"+minExpirationSeconds+"秒");
		}
		
		@SuppressWarnings("unchecked")
		MapCache<K, V> mapCache = (MapCache<K, V>)CacheData.get(masterKey);
		if (mapCache == null) {
			synchronized(CacheFactory.class) {
				if (CacheData.get(masterKey) == null) {
					Calendar expirationTime = null;
					if (expirationSeconds != 0) {
						expirationTime = Calendar.getInstance();
						expirationTime.add(Calendar.SECOND, expirationSeconds);
					}
					//实例化一个MapCache类， 将把它放入主缓存中
					mapCache = new MapCache<K,V>(new ConcurrentHashMap<K, V>(), expirationSeconds, expirationTime);
					CacheData.put(masterKey, mapCache);
				}
			}
		}
		return mapCache;
	}
	
	/**
	 * 得到列表类型的缓存
	 * @param masterKey
	 * @param expirationSeconds
	 * @return
	 */
	public static<E> ListCache<E> getListCache(String masterKey, int expirationSeconds) {
		
		if (expirationSeconds != 0 && expirationSeconds < minExpirationSeconds) {
			throw new ExpirationSecondsException("缓存过期秒数不能小于"+minExpirationSeconds+"秒");
		}
		
		@SuppressWarnings("unchecked")
		ListCache<E> listCache = (ListCache<E>)CacheData.get(masterKey);
		if (listCache == null) {
			synchronized(CacheFactory.class) {
				if (CacheData.get(masterKey) == null) {
					Calendar expirationTime = null;
					if (expirationSeconds != 0) {
						expirationTime = Calendar.getInstance();
						expirationTime.add(Calendar.SECOND, expirationSeconds);
					}
					//实例化一个ListCache类， 将把它放入主缓存中
					listCache = new ListCache<E>(new CopyOnWriteArrayList<E>(), expirationSeconds, expirationTime);
					CacheData.put(masterKey, listCache);
				}
			}
		}
		return listCache;
	}
}
